package com.lisp.algorithm.concurrent;

import java.util.concurrent.atomic.AtomicReference;

public class ConcurrentStack<V> {

    private AtomicReference<Node> top = new AtomicReference<>();
    
    public V pop() {
        Node oldTop = null;
        Node newTop = null;
        do {
            oldTop = top.get();
            if(oldTop == null) {
                return null;
            }
            newTop = oldTop.next;
        } while(!top.compareAndSet(oldTop, newTop));
        return oldTop.value;
    }
    
    public void push(V value) {
        Node newTop = new Node(value);
        Node oldTop = null;
        do {
            oldTop = top.get();
            newTop.next = oldTop;
        } while(!top.compareAndSet(oldTop, newTop));
    }
    
    class Node {
        private final V value;
        private Node next;
        
        Node(V val) {
            this.value = val;
        }
    }
}
